// $Id: ustring.cpp 2 2009-09-02 08:47:42Z joseph2002 $
/*
 * Copyright 2009 Joseph Wu
 * Distributed under the Boost Software License, Version 1.0.
 * (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
 *
 * For more information, see http://xpcomplus.sourceforge.net
 */

#define XPCOM_SOURCE

#include <xpcom/config.hpp>
#include <algorithm>
#include <xpcom/exception.hpp>
#include <xpcom/ustring.hpp>
#include "api/string.hpp"

namespace xpcom {

ustring::ustring() :
    base_type()
{
}

ustring::ustring(const ustring& s) :
    base_type(s)
{
}

ustring::ustring(const wstring& s)
{
    init();

    result r = ::NS_UTF16ToCString(s, NS_CSTRING_ENCODING_UTF8, *this);
    if (r.failed()) {
        finish();
        throw_exception(r);
    }
}

ustring::ustring(const string& s) :
    base_type(s)
{
}

ustring::ustring(const string& s, size_type pos, size_type n) :
    base_type(s, pos, n)
{
}

ustring::ustring(const value_type* s, size_type n) :
    base_type(s, n)
{
}

ustring::ustring(size_type n, value_type c) :
    base_type(n, c)
{
}

ustring::~ustring()
{
}

ustring& ustring::assign(const wstring& s)
{
    ::NS_UTF16ToCString(s, NS_CSTRING_ENCODING_UTF8, *this) | throw_exception;
    return *this;
}

ustring ustring::substr(size_type pos, size_type n) const
{
    data_type d;
    get_data(d);

    if (pos > d.length)
        throw_out_of_range();

    // If acquiring the whole string, return this to avoid copying
    if (pos == 0 && (n == npos || n == d.length)) {
        return *this;
    } else {
        // XXX Do not use init_substring flag,
        // cause we need to keep the string null-terminated
        return ustring(d.data + pos, (std::min)(n, d.length - pos));
    }
}

void ustring::to_wstr(wstring& s) const
{
    ::NS_CStringToUTF16(*this, NS_CSTRING_ENCODING_UTF8, s) | throw_exception;
}

wstring ustring::wstr() const
{
    wstring s;
    to_wstr(s);
    return s;
}

} // namespace xpcom
